"""

Simple JSON-RPC Dispatcher.

This version is a modified of the 
SimpleJSONRPCDispatcher created by David McNab.

It's used for the django-simp project and modified by Felix Marthaler

"""
# This implementation was modified from the SimpleJSONRPCServer module 
# by Felix Marthaler

# This implementation was converted from SimpleXMLRPCServer by
# David McNab (david@rebirthing.co.nz)

# Original SimpleXMLRPCServer module was written by Brian
# Quinlan (brian@sweetapp.com), Based on code written by Fredrik Lundh.
import sys, traceback

import xmlrpclib
from xmlrpclib import Fault

import SimpleXMLRPCServer
from django.utils import simplejson

import traceback

class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
    """Mix-in class that dispatches JSON-RPC requests.
    Based on SimpleXMLRPCDispatcher, but overrides
    _marshaled_dispatch for JSON-RPC

    This class is used to register JSON-RPC method handlers
    and then to dispatch them. There should never be any
    reason to instantiate this class directly.
    """
    def dispatch(self, data, dispatch_method = None):
        """Dispatches a JSON-RPC method from marshalled (JSON) data.
    
        JSON-RPC methods are dispatched from the marshalled (JSON) data
        using the _dispatch method and the result is returned as
        marshalled data. For backwards compatibility, a dispatch
        function can be provided as an argument (see comment in
        SimpleJSONRPCRequestHandler.do_POST) but overriding the
        existing method through subclassing is the prefered means
        of changing method dispatch behavior.
        """
        rawreq = simplejson.loads(data)
    
        #params, method = xmlrpclib.loads(data)
        id = rawreq.get('id', 0)
        method = rawreq['method']
        params = rawreq.get('params', [])
        
        responseDict = {'id':id}
    
        # generate response
        try:
            if dispatch_method is not None:
                response = dispatch_method(method, params)
            else:
                response = self._dispatch(method, params)
            ## wrap response in a singleton tuple
            #response = (response,)
            #response = xmlrpclib.dumps(response, methodresponse=1)
            responseDict['result'] = response
        except Fault, fault:
            #response = xmlrpclib.dumps(fault)
            responseDict['error'] = repr(response)
        except:
            # report exception back to server
            #response = xmlrpclib.dumps(
            #    xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
            #    )
            responseDict['error'] = "%s:%s\n%s" % (sys.exc_type, sys.exc_value, traceback.format_exc())
    
        return simplejson.dumps(responseDict)
    




